<?php
/**
 ***********************************************************************************************************************
 * 队列使用Redis实现
 ***********************************************************************************************************************
 */
namespace artisan;

/**
 * Class queue
 * @package artisan
 */
class queue
{
    /**
     * @var array
     */
    private static $config = [];

    /**
     * @var array
     */
    private static $instances = [];

    /**
     * 推入一个队列元素
     * 注：仅仅支持字符串，或二维字符串数组
     * @param $key
     * @param $string
     * @return int
     */
    public static function push($key, $val)
    {
        return self::connect()->push($key, $val);
    }

    /**
     * 弹出一个队列元素
     * @param $key
     * @return bool|string
     */
    public static function pop($key)
    {
        return self::connect()->pop($key);
    }


    /**
     * 获取队列长度
     * @param $key
     * @return int
     */
    public static function len($key)
    {
        return self::connect()->len($key);
    }

    /**
     * 删除一个队列
     * @param $key
     * @return int
     */
    public static function del($key)
    {
        return self::connect()->del($key);
    }

    /**
     * 新版支持选择服务器 这里并不没有创建连接 采用的是延迟连接的方式 直到真正调用redis方法才会建立连接 减少连接浪费
     * @param string $alias
     * @return cache\PHPredisDriver
     */
    public static function connect($alias = '')
    {
        // 不选择服务器，使用默认服务器
        $alias = (empty($alias) || !is_string($alias) || is_numeric($alias)) ? 'base' : $alias;
        if(empty(self::$instances[$alias])) {
            self::$instances[$alias] = new \artisan\cache\PHPredisDriver(self::getServer($alias),$alias,true);
            //self::$instances[$alias] = new \artisan\cache\PredisDriver(self::getServer($alias),$alias,true);
        }
        return self::$instances[$alias];
    }

    /**
     * 按权重选择服务器
     * @param string $alias
     * @return array
     */
    public static function getServer($alias)
    {
        // 检测配置文件
        if(empty(self::$config) && !(self::$config = config::get('queue'))) {
            exit('Error queue config give!');
        }

        // 兼容旧版配置
        $config = !empty(self::$config[$alias]) ? self::$config[$alias] : self::$config;

        // 按权重选择服务器
        $count = 0;
        $servers = array();
        foreach($config  as $server) {
            if(!isset($server['enable']) || $server['enable'] == true) {
                $server['weight'] = empty($server['weight']) ? 100 : $server['weight'];
                $servers[] = $server;
                $count++;
            }
        }

        $weight_sum = 0;
        foreach($servers as $val) {
            $weight_sum += $val['weight'];
        }

        $roll = rand(1, $weight_sum);
        $tmp = 0;
        $key = 0;
        foreach($servers as $server_key => $server) {
            $min = $tmp;
            $tmp += $server['weight'];
            $max = $tmp;
            if ($roll > $min && $roll <= $max) {
                $key = $server_key;
                break;
            }
        }

        return [
            'host' => $servers[$key]['host'],
            'port' => $servers[$key]['port'],
            'timeout' => empty($servers[$key]['timeout']) ? '' : $servers[$key]['timeout']
        ];
    }

    /**
     * @return \Redis
     */
    public static function getInstance()
    {
        return self::connect()->getInstance();
    }
}